io-png.c: changed g_malloc call for pixles to art_alloc (to be "correct")
authorMark Crichton <crichton@src.gnome.org>
Tue, 29 Jun 1999 06:07:14 +0000 (06:07 +0000)
committerMark Crichton <crichton@src.gnome.org>
Tue, 29 Jun 1999 06:07:14 +0000 (06:07 +0000)
io-png.c: changed g_malloc call for pixles to art_alloc (to be "correct")

io-gif.c: implemented GIF file loading.

gdk-pixbuf/io-gif.c [new file with mode: 0644]
gdk-pixbuf/io-png.c

diff --git a/gdk-pixbuf/io-gif.c b/gdk-pixbuf/io-gif.c
new file mode 100644 (file)
index 0000000..c3252db
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * io-png.c: GdkPixBuf I/O for GIF files.
+ * ...second verse, same as the first...
+ *
+ * Author:
+ *    Mark Crichton <crichton@gimp.org>
+ *
+ */
+#include <config.h>
+#include <stdio.h>
+#include <glib.h>
+#include "gdk-pixbuf.h"
+#include "gdk-pixbuf-io.h"
+#include <gif_lib.h>
+
+/* Shared library entry point */
+GdkPixBuf *image_load(FILE * f)
+{
+       gint fn, is_trans, done;
+       gint t_color = -1;
+       gint w, h, i, j;
+       art_u8 *pixels, *tmpptr;
+       GifFileType *gif;
+       GifRowType *rows;
+       GifRecordType rec;
+       ColorMapObject *cmap;
+       int intoffset[] = {0, 4, 2, 1};
+       int intjump[] = {8, 8, 4, 2};
+
+       GdkPixBuf *pixbuf;
+
+       g_return_val_if_fail(f != NULL, NULL);
+
+       fn = fileno(f);
+       gif = DGifOpenFileHandle(fn);
+
+       if (!gif) {
+               g_error("DGifOpenFilehandle FAILED");
+               PrintGifError();
+               return NULL;
+       }
+       /* Now we do the ungodly mess of loading a GIF image
+        * I used to remember when I liked this file format...
+        * of course, I still coded in assembler then.
+        * This comes from gdk_imlib, with some cleanups.
+        */
+
+       do {
+               if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
+                       PrintGifError();
+                       rec = TERMINATE_RECORD_TYPE;
+               }
+               if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done)) {
+                       if (DGifGetImageDesc(gif) == GIF_ERROR) {
+                               PrintGifError();
+                               rec = TERMINATE_RECORD_TYPE;
+                       }
+                       w = gif->Image.Width;
+                       h = gif->Image.Height;
+                       rows = g_malloc(h * sizeof(GifRowType *));
+                       if (!rows) {
+                               DGifCloseFile(gif);
+                               return NULL;
+                       }
+                       for (i = 0; i < h; i++) {
+                               rows[i] = g_malloc(w * sizeof(GifPixelType));
+                               if (!rows[i]) {
+                                       DGifCloseFile(gif);
+                                       for (i = 0; i < h; i++)
+                                               if (rows[i])
+                                                       g_free(rows[i]);
+                                       free(rows);
+                                       return NULL;
+                               }
+                       }
+                       if (gif->Image.Interlace) {
+                               for (i = 0; i < 4; i++) {
+                                       for (j = intoffset[i]; j < h; j += intjump[i])
+                                               DGifGetLine(gif, rows[j], w);
+                               }
+                       } else {
+                               for (i = 0; i < h; i++)
+                                       DGifGetLine(gif, rows[i], w);
+                       }
+                       done = TRUE;
+               } else if (rec == EXTENSION_RECORD_TYPE) {
+                       gint ext_code;
+                       GifByteType *ext;
+
+                       DGifGetExtension(gif, &ext_code, &ext);
+                       while (ext) {
+                               if ((ext_code == GRAPHICS_EXT_FUNC_CODE) &&
+                                   (ext[1] & 1) && (t_color < 0)) {
+                                       is_trans = TRUE;
+                                       t_color = (gint) ext[4];
+                               }
+                               ext = NULL;
+                               DGifGetExtensionNext(gif, &ext);
+                       }
+               }
+       }
+       while (rec != TERMINATE_RECORD_TYPE);
+
+       /* Ok, we're loaded, now to convert from indexed -> RGB
+        * with alpha if necessary
+        */
+
+       if (is_trans)
+               pixels = art_alloc(h * w * 4);
+       else
+               pixels = art_alloc(h * w * 3);
+       tmpptr = pixels;
+
+       if (!pixels)
+               return NULL;
+
+       /* The meat of the transformation */
+       /* Get the right palette */
+       cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
+
+       /* Unindex the data, and pack it in RGB(A) order.
+        * Note for transparent GIFs, the alpha is set to 0
+        * for the transparent color, and 0xFF for everything else.
+        * I think that's right...
+        */
+
+       for (i = 0; i < h; i++) {
+               for (j = 0; j < w; j++) {
+                       tmpptr[0] = cmap->Colors[rows[i][j]].Red;
+                       tmpptr[1] = cmap->Colors[rows[i][j]].Green;
+                       tmpptr[2] = cmap->Colors[rows[i][j]].Blue;
+                       if (is_trans && (rows[i][j] == t_color))
+                               tmpptr[3] = 0;
+                       else
+                               tmpptr[3] = 0xFF;
+                       tmpptr += (is_trans ? 3 : 4);
+               }
+       }
+
+       /* Ok, now stuff the GdkPixBuf with goodies */
+
+       pixbuf = g_new(GdkPixBuf, 1);
+
+       if (is_trans)
+               pixbuf->art_pixbuf = art_pixbuf_new_rgba(pixels, w, h, (w * 4));
+       else
+               pixbuf->art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
+
+       /* Ok, I'm anal...shoot me */
+       if (!(pixbuf->art_pixbuf))
+               return NULL;
+       pixbuf->ref_count = 0;
+       pixbuf->unref_func = NULL;
+
+       return pixbuf;
+}
index 70d2df645f1e2bcc3d6c4bbc58331f3e1911d95a..789a086454210df27ea8993c4026ce3f2478ef46 100644 (file)
@@ -91,7 +91,7 @@ GdkPixBuf *image_load(FILE * f)
         else
                 bpp = 3;
 
-       pixels = g_malloc(w*h*bpp);
+       pixels = art_alloc(w*h*bpp);
        rows = g_malloc(h*sizeof(png_bytep));
 
        if ((!pixels) || (!rows)) {
@@ -126,7 +126,7 @@ GdkPixBuf *image_load(FILE * f)
                        temp[1] = rowdata[(x*bpp)+1];
                        temp[2] = rowdata[(x*bpp)+2];
                        if (bpp == 4)
-                               temp[3] = rowdata[(x*4)+3];
+                               temp[3] = rowdata[(x*bpp)+3];
                        temp += bpp;
                }
                g_free(rows[y]);